#    This file is part of robo-ircbot.
#
#    robo-ircbot is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    robo-ircbot is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with robo-ircbot.  If not, see <http://www.gnu.org/licenses/>.

package App::Modular::Module::Commands;
use strict;
use warnings;
use threads('exit' => 'threads_only');
use base qw(App::Modular::Module);

print ":: Commands module loaded.\n";

# Events we want to receive.
sub events { return "PRIVMSG"; }

sub help {
        return (
                "Some core commands.",
                ".reload         Reload all modules and configuration.",
                ".quit           Disconnect and exit.",
                ".raw <msg>      Send some raw text to the IRC connection socket.",
                ".lastlog <num>  Show <num> last entries from log.",
                ".clearlog       Clear the log file.",
                ".disconnect     Disconnect from the server.",
                ".nick <str>     Change my nickname.",
                ".version        My version information."
        );
}

# PRIVMSG events.
sub event_privmsg
{
        shift;
        my $e = shift;

        my $auth = $e->robo->mod("Auth") || return;

        # Admin commands.
        if ($auth->is_authed($e->from)) {
                # Reload
                if ($e->data eq ".reload") {
                        $e->s("PRIVMSG ".$e->dest." :Reloading configuration and modules.");
                        threads->create('reload_thread');
                # Quit
                } elsif ($e->data eq ".quit") {
                        $e->s("PRIVMSG ".$e->dest." :Later nubs.");
                        $e->s("QUIT :Later nubs.");
                        exit 0;
                # Raw
                } elsif ($e->data =~ /^\.raw (.+)/) {
                        $e->s($1);
                # Last N lines of log file.
                } elsif ($e->data =~ /^\.lastlog (\d+)/) {
                        # Make sure logging has been enabled.
                        if ($e->cfg->get_cfg("log/enabled") ne "yes") {
                                $e->s("PRIVMSG ".$e->dest." :Sorry, logging has been disabled!");
                                return;
                        }

                        # Open log for reading.
                        if (!open(LOGIN, "<".$e->cfg->get_cfg("log/file"))) {
                                $e->s("PRIVMSG ".$e->dest." :Cannot open log file for reading!");
                                return;
                        }

                        # Read all lines into an array.
                        my @lines = <LOGIN>;

                        # We are done with the stream.
                        close(LOGIN);

                        # Print the last N lines of the log.
                        my $start = $#lines - $1;
                        if ($start < 1) { $start = 1; }
                        for (my $i = $start + 1; $i <= $#lines; $i++) {
                                $e->s("PRIVMSG ".$e->dest." :Line ".$i.": ".$lines[$i]);
                                sleep(1);
                        }
                # Clear the log file.
                } elsif ($e->data =~ /^\.clearlog$/) {
                        $e->robo->log_clear();
                        $e->s("PRIVMSG ".$e->dest." :Cleared the log master!");
                # Disconnect from IRC server.
                } elsif ($e->data =~ /^\.disconnect$/) {
                        $e->s("PRIVMSG ".$e->dest." :I'm outtie yo.");
                        $e->s("QUIT :Reconnecting...");
                # Change current bot nick.
                } elsif ($e->data =~ /^\.nick (\w+)$/) {
                        $e->s("NICK ".$1);
                        $e->cfg->nick($1);
                        $e->robo->log(":: Changed nick to: ".$1);
                }
        }

        # Version
        if ($e->data eq ".version") {
                $e->s("PRIVMSG ".$e->dest." :robo v".$e->cfg->get_cfg("version")." - pwnagest b0t in teh w0rld.");

        # Help
        } elsif ($e->data =~ /^\.help(\s+(\w+))?$/) {
                if (!$1) {
                        my @mods = $e->robo->{mod}->{mod}->modules();
                        $e->s("PRIVMSG ".$e->dest." :.help <module name>");
                        $e->s("PRIVMSG ".$e->dest." :List: ".join(" ", @mods));

                        return;
                }

                my $m = $e->robo->mod($2) || return;
                my @help = $m->help();

                $e->s("PRIVMSG ".$e->dest." :".$2.": ".$help[0]);

                $e->robo->log("items: ".$#help);

                for (my $i = 1; $i <= $#help; $i++) {
                        $e->s("PRIVMSG ".$e->dest." :".$help[$i]);
                        sleep(1);
                }
        }
}

# Reload thread.
sub reload_thread
{
        my $pid = `cat robo.pid`;
        chomp $pid;
        system("kill", "-SIGHUP", $pid);

        system("killall", "--signal", "SIGHUP", "robo");
        threads->exit() if threads->can('exit');
        exit(0);
}

1;
